package cn.assumejson.springframework.aop.framework.autoproxy;

import cn.assumejson.springframework.aop.MethodMatcher;
import cn.assumejson.springframework.aop.Pointcut;
import cn.assumejson.springframework.aop.aspectj.AspectJExpressionPointcut;
import cn.assumejson.springframework.aop.support.ComposablePointcut;
import cn.hutool.core.lang.Assert;
import org.aopalliance.aop.Advice;

import java.lang.reflect.Method;

/**
 * @author gang.Li
 * @version 1.0
 * @since 1.0 2021/12/9 15:56
 */
public abstract class AbstractAspectJAdvice implements Advice {

    private final Class<?> declaringClass;

    private final String methodName;

    private final Class<?>[] parameterTypes;

    protected transient Method aspectJAdviceMethod;

    private final AspectJExpressionPointcut pointcut;

    private String aspectName = "";

    public AbstractAspectJAdvice(
            Method aspectJAdviceMethod, AspectJExpressionPointcut pointcut) {

        Assert.notNull(aspectJAdviceMethod, "Advice method must not be null");
        this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
        this.methodName = aspectJAdviceMethod.getName();
        this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
        this.aspectJAdviceMethod = aspectJAdviceMethod;
        this.pointcut = pointcut;
    }

    public Pointcut buildSafePointcut() {
        Pointcut pc = getPointcut();

        return new ComposablePointcut(pc.getClassFilter(), this.aspectJAdviceMethod);
    }

    private Pointcut getPointcut() {
        return this.pointcut;
    }

    /**
     * Set the name of the aspect (bean) in which the advice was declared.
     */
    public void setAspectName(String name) {
        this.aspectName = name;
    }

    public String getAspectName() {
        return this.aspectName;
    }

}
